#include <cstdio>
#include <string>
#include <iostream>
#include <time.h>
#include <cstdarg>
#include <fstream>
#include <pthread.h>
#include "LockGuard.hpp"

// 可变参数的宏定义
#define Log(level, format, ...) LogMessage(__FILE__, __LINE__, level, format, ##__VA_ARGS__)
#define EnableFile()   \
    do                 \
    {                  \
        Issave = true; \
    } while (0)
#define EnableScreen()  \
    do                  \
    {                   \
        Issave = false; \
    } while (0)

bool Issave = false;
const std::string filename = "log.txt";
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
using namespace std;
enum Level
{
    DEBUG = 0,
    INFO,
    WARNING,
    ERROR,
    FATAL
};
void GetSave(const string &filename, const string &messages)
{
    ofstream out(filename, ios::app);//是一个文件打开模式标志，用于指定文件打开的方式。ios::app表示以追加模式打开文件
    if (!out.is_open())
    {
        return;
    }
    out << messages;//通过out对象使用如<<运算符等成员函数来向文件写入数据
    out.close();
}
string GetLevel(int level)
{
    switch (level)
    {
    case DEBUG:
        return "Debug";
    case INFO:
        return "Info";
    case WARNING:
        return "Warning";
    case ERROR:
        return "Error";
    case FATAL:
        return "Fatal";
    default:
        return "None";
    }
}
string GetTime()
{
    time_t cur_time = time(nullptr);
    struct tm *format_time = localtime(&cur_time);
    // 判断
    if (format_time == nullptr)
        return "None";
    char time_buffer[1024];
    snprintf(time_buffer, sizeof(time_buffer), "%d-%d-%d %d:%d:%d",
             format_time->tm_year + 1900, format_time->tm_mon + 1,
             format_time->tm_mday, format_time->tm_hour,
             format_time->tm_min, format_time->tm_sec);
    return time_buffer;
}
// 日志格式：日志等级  时间   代码所在文件/行数  日志内容
void LogMessage(string name, int line, int level, const char *format, ...)
{
    string Levelstr = GetLevel(level);
    string timestr = GetTime();
    char buffer[1024];
    va_list arg; // 可变参数
    va_start(arg, format);//将*arg变为*format类型
    vsnprintf(buffer, sizeof(buffer), format, arg);
    va_end(arg);
    string messages = "[" + GetLevel(level) + "] " +
                      "[ " + GetTime() + "] " + "[ " + name + "] " +
                      "[ " + to_string(line) + "] " + "[ " + buffer + "] " + "\n";
    // 打印前加锁，保护数据安全
    LockGuard lockguard(&lock);
    if (!Issave)
        cout << messages << endl;
    else
    {
        GetSave(filename, messages);
    }
}
